/*
* Copyright 2013 Jun Ohtani
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.johtani.elasticsearch.rest.action.admin.indices.analyze;
import info.johtani.elasticsearch.action.admin.indices.extended.analyze.ExtendedAnalyzeAction;
import info.johtani.elasticsearch.action.admin.indices.extended.analyze.ExtendedAnalyzeRequest;
import info.johtani.elasticsearch.action.admin.indices.extended.analyze.ExtendedAnalyzeResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.RestChannel;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.action.support.RestActions;
import org.elasticsearch.rest.action.support.RestToXContentListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static org.elasticsearch.rest.RestRequest.Method.*;
/**
* Extended _analyze for REST endpoint
*/
public class RestExtendedAnalyzeAction extends BaseRestHandler {
@Inject
public RestExtendedAnalyzeAction(Settings settings, Client client, RestController controller) {
super(settings, controller, client);
controller.registerHandler(GET, "/_extended_analyze", this);
controller.registerHandler(GET, "/{index}/_extended_analyze", this);
controller.registerHandler(POST, "/_extended_analyze", this);
controller.registerHandler(POST, "/{index}/_extended_analyze", this);
}
@Override
public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) {
String[] text = request.paramAsStringArrayOrEmptyIfAll("text");
ExtendedAnalyzeRequest analyzeRequest = new ExtendedAnalyzeRequest(request.param("index"));
analyzeRequest.text(text);
analyzeRequest.analyzer(request.param("analyzer"));
analyzeRequest.field(request.param("field"));
analyzeRequest.tokenizer(request.param("tokenizer"));
analyzeRequest.tokenFilters(request.paramAsStringArray("token_filters", request.paramAsStringArray("filters", analyzeRequest.tokenFilters())));
analyzeRequest.charFilters(request.paramAsStringArray("char_filters", analyzeRequest.charFilters()));
analyzeRequest.attributes(request.paramAsStringArray("attributes", null));
analyzeRequest.shortAttributeName(request.paramAsBoolean("use_short_attr", false));
if (request.hasContent() || request.hasParam("source")) {
XContentType type = guessBodyContentType(request);
if (type == null) {
if (text == null || text.length == 0) {
text = new String[]{ RestActions.getRestContent(request).toUtf8()};
analyzeRequest.text(text);
}
} else {
buildFromContent(RestActions.getRestContent(request), analyzeRequest);
}
}
client.admin().indices().execute(ExtendedAnalyzeAction.INSTANCE, analyzeRequest, new RestToXContentListener<ExtendedAnalyzeResponse>(channel));
}
public static XContentType guessBodyContentType(final RestRequest request) {
final BytesReference restContent = RestActions.getRestContent(request);
if (restContent == null) {
return null;
}
return XContentFactory.xContentType(restContent);
}
public static void buildFromContent(BytesReference content, ExtendedAnalyzeRequest analyzeRequest) throws IllegalArgumentException {
try (XContentParser parser = XContentHelper.createParser(content)) {
if (parser.nextToken() != XContentParser.Token.START_OBJECT) {
throw new IllegalArgumentException("Malformed content, must start with an object");
} else {
XContentParser.Token token;
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if ("text".equals(currentFieldName) && token == XContentParser.Token.VALUE_STRING) {
analyzeRequest.text(parser.text());
} else if ("text".equals(currentFieldName) && token == XContentParser.Token.START_ARRAY) {
List<String> texts = new ArrayList<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
if (token.isValue() == false) {
throw new IllegalArgumentException(currentFieldName + " array element should only contain text");
}
texts.add(parser.text());
}
analyzeRequest.text(texts.toArray(Strings.EMPTY_ARRAY));
} else if ("analyzer".equals(currentFieldName) && token == XContentParser.Token.VALUE_STRING) {
analyzeRequest.analyzer(parser.text());
} else if ("field".equals(currentFieldName) && token == XContentParser.Token.VALUE_STRING) {
analyzeRequest.field(parser.text());
} else if ("tokenizer".equals(currentFieldName) && token == XContentParser.Token.VALUE_STRING) {
analyzeRequest.tokenizer(parser.text());
} else if (("token_filters".equals(currentFieldName) || "filters".equals(currentFieldName)) && token == XContentParser.Token.START_ARRAY) {
List<String> filters = new ArrayList<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
if (token.isValue() == false) {
throw new IllegalArgumentException(currentFieldName + " array element should only contain token filter's name");
}
filters.add(parser.text());
}
analyzeRequest.tokenFilters(filters.toArray(Strings.EMPTY_ARRAY));
} else if ("char_filters".equals(currentFieldName) && token == XContentParser.Token.START_ARRAY) {
List<String> charFilters = new ArrayList<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
if (token.isValue() == false) {
throw new IllegalArgumentException(currentFieldName + " array element should only contain char filter's name");
}
charFilters.add(parser.text());
}
analyzeRequest.tokenFilters(charFilters.toArray(Strings.EMPTY_ARRAY));
} else if ("attributes".equals(currentFieldName) && token == XContentParser.Token.START_ARRAY){
List<String> attributes = new ArrayList<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
if (token.isValue() == false) {
throw new IllegalArgumentException(currentFieldName + " array element should only contain attribute name");
}
attributes.add(parser.text());
}
analyzeRequest.attributes(attributes.toArray(Strings.EMPTY_ARRAY));
} else if ("use_short_attr".equals(currentFieldName) && token == XContentParser.Token.VALUE_BOOLEAN) {
analyzeRequest.shortAttributeName(parser.booleanValue());
} else {
throw new IllegalArgumentException("Unknown parameter [" + currentFieldName + "] in request body or parameter is of the wrong type[" + token + "] ");
}
}
}
} catch (IOException e) {
throw new IllegalArgumentException("Failed to parse request body", e);
}
}
}